package com.aliyun.messagemgt.application.service.Impl;

import com.aliyun.messagemgt.common.enums.IsEnabledEnum;
import com.aliyun.messagemgt.application.service.BaseReceiveGroupService;
import com.aliyun.messagemgt.converter.BaseReceiveGroupConverter;
import com.aliyun.messagemgt.common.errorcode.CommonErrorCode;
import com.aliyun.messagemgt.common.exceptions.BaseException;
import com.aliyun.messagemgt.domain.repository.IBaseReceiveGroupRangeRepository;
import com.aliyun.messagemgt.domain.repository.IBaseReceiveGroupRepository;
import com.aliyun.messagemgt.dto.base.*;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName: BaseReceiveGroupServiceImpl
 * @Description:
 * @Author: wugongzi
 * @Date: 2021/9/28 10:41
 * @Version: 1.0
 */
@Service
public class BaseReceiveGroupServiceImpl implements BaseReceiveGroupService {

    @Autowired
    private IBaseReceiveGroupRepository baseReceiveGroupRepository;
    @Autowired
    private IBaseReceiveGroupRangeRepository baseReceiveGroupRangeRepository;

    @Override
    public PageInfo<BaseReceiveGroupDetailDTO> page(BaseReceiveGroupQry baseReceiveGroupQry) {
        // 分页查询接收组
        PageInfo<BaseReceiveGroupDTO> baseReceiveGroupDTOPageInfo = baseReceiveGroupRepository.page(baseReceiveGroupQry);
        PageInfo<BaseReceiveGroupDetailDTO> baseReceiveGroupDetailDTOPageInfo = BaseReceiveGroupConverter.INSTANCE.baseReceiveGroupDTOPageInfo2baseReceiveGroupDetailDTOPageInfo(baseReceiveGroupDTOPageInfo);
        // 查询接收组范围
        List<BaseReceiveGroupDetailDTO> baseReceiveGroupDetailDTOList = baseReceiveGroupDetailDTOPageInfo.getList();
        if (CollectionUtils.isNotEmpty(baseReceiveGroupDetailDTOList)) {
            List<Long> groupIdList = baseReceiveGroupDetailDTOList.stream().map(BaseReceiveGroupDetailDTO::getId).collect(Collectors.toList());
            List<BaseReceiveGroupRangeDTO> baseReceiveGroupRangeDTOList = baseReceiveGroupRangeRepository.selectByGroupIdList(groupIdList);
            Map<Long, List<BaseReceiveGroupRangeDTO>> baseReceiveGroupRangeDTOMap = baseReceiveGroupRangeDTOList.stream().collect(Collectors.groupingBy(BaseReceiveGroupRangeDTO::getGroupId));
            baseReceiveGroupDetailDTOList.forEach(
                    baseReceiveGroupDetailDTO -> {
                        Long id = baseReceiveGroupDetailDTO.getId();
                        List<BaseReceiveGroupRangeDTO> baseReceiveGroupRangeDTOS = baseReceiveGroupRangeDTOMap.get(id);
                        baseReceiveGroupDetailDTO.setBaseReceiveGroupRangeDTOList(baseReceiveGroupRangeDTOS);
                    }
            );
        }
        return baseReceiveGroupDetailDTOPageInfo;
    }

    @Override
    @Transactional
    public Boolean delete(Long id) {
        int rangeDeleteCount = baseReceiveGroupRangeRepository.deleteByGroupId(id);
        int deleteCount = baseReceiveGroupRepository.deleteById(id);
        return true;
    }

    @Override
    @Transactional
    public Boolean update(BaseReceiveGroupUpdateCmd cmd) {
        // 校验参数
        checkBaseReceiveGroupUpdateCmd(cmd);
        int updateCount = baseReceiveGroupRepository.update(cmd);
        List<BaseReceiveGroupRangeAddCmd> baseReceiveGroupRangeAddCmdList = cmd.getBaseReceiveGroupRangeAddCmdList();
        if (CollectionUtils.isNotEmpty(baseReceiveGroupRangeAddCmdList)) {
            Long groupId = cmd.getId();
            int rangeDeleteCount = baseReceiveGroupRangeRepository.deleteByGroupId(groupId);
            baseReceiveGroupRangeAddCmdList.forEach(rangeCmd -> rangeCmd.setGroupId(groupId));
            baseReceiveGroupRangeRepository.add(baseReceiveGroupRangeAddCmdList);
        }
        return true;
    }

    private void checkBaseReceiveGroupUpdateCmd(BaseReceiveGroupUpdateCmd cmd) {
        // 校验接收组是否存在
        BaseReceiveGroupQry qry = new BaseReceiveGroupQry();
        Long id = cmd.getId();
        qry.setId(id);
        qry.setTenantCode(cmd.getTenantCode());
        qry.setIsDeleted("N");
        BaseReceiveGroupDTO baseReceiveGroupDTO = getOne(qry);
        if (Objects.isNull(baseReceiveGroupDTO)) {
            throw new BaseException(CommonErrorCode.BASE_RECEIVE_GROUP_IS_NOT_EXITED);
        }
        // 校验接收组编码-租户唯一性
        String receiveGroupCode = cmd.getReceiveGroupCode();
        if(StringUtils.isNotBlank(receiveGroupCode)){
            qry = new BaseReceiveGroupQry();
            qry.setReceiveGroupCode(receiveGroupCode);
            qry.setTenantCode(cmd.getTenantCode());
            qry.setIsDeleted("N");
            baseReceiveGroupDTO = getOne(qry);
            if (Objects.nonNull(baseReceiveGroupDTO) && !id.equals(baseReceiveGroupDTO.getId())) {
                throw new BaseException(CommonErrorCode.BASE_RECEIVE_GROUP_IS_EXITED);
            }
        }
    }

    private List<BaseReceiveGroupDTO> getList(BaseReceiveGroupQry qry) {
        return baseReceiveGroupRepository.getList(qry);
    }

    @Override
    @Transactional
    public Boolean add(BaseReceiveGroupAddCmd cmd) {
        // 接收组编码唯一性校验
        BaseReceiveGroupQry qry = new BaseReceiveGroupQry();
        qry.setReceiveGroupCode(cmd.getReceiveGroupCode());
        qry.setTenantCode(cmd.getTenantCode());
        qry.setIsDeleted("N");
        BaseReceiveGroupDTO baseReceiveGroupDTO = getOne(qry);
        if (Objects.nonNull(baseReceiveGroupDTO)) {
            throw new BaseException(CommonErrorCode.BASE_RECEIVE_GROUP_IS_EXITED);
        }
        baseReceiveGroupRepository.add(cmd);
        List<BaseReceiveGroupRangeAddCmd> baseReceiveGroupRangeAddCmdList = cmd.getBaseReceiveGroupRangeAddCmdList();
        baseReceiveGroupRangeAddCmdList.forEach(rangeCmd -> rangeCmd.setGroupId(cmd.getId()));
        baseReceiveGroupRangeRepository.add(baseReceiveGroupRangeAddCmdList);
        return true;
    }

    private BaseReceiveGroupDTO getOne(BaseReceiveGroupQry qry) {
        return baseReceiveGroupRepository.get(qry);
    }

    @Override
    public BaseReceiveGroupDetailDTO get(Long id) {
        BaseReceiveGroupDTO baseReceiveGroupDTO = baseReceiveGroupRepository.get(id);
        BaseReceiveGroupDetailDTO baseReceiveGroupDetailDTO = BaseReceiveGroupConverter.INSTANCE.baseReceiveGroupDTO2baseReceiveGroupDetailDTO(baseReceiveGroupDTO);
        if (Objects.nonNull(baseReceiveGroupDetailDTO)) {
            List<BaseReceiveGroupRangeDTO> baseReceiveGroupRangeDTOList = baseReceiveGroupRangeRepository.selectByGroupId(id);
            baseReceiveGroupDetailDTO.setBaseReceiveGroupRangeDTOList(baseReceiveGroupRangeDTOList);
        }
        return baseReceiveGroupDetailDTO;
    }

    @Override
    public List<BaseReceiveGroupDetailDTO> selectList(String tenantCode, List<String> receiveGroupCodes) {
        List<BaseReceiveGroupDTO> baseReceiveGroupDTOList = baseReceiveGroupRepository.selectList(tenantCode, receiveGroupCodes, IsEnabledEnum.Y.getCode());
        List<BaseReceiveGroupDetailDTO> baseReceiveGroupDetailDTOList = BaseReceiveGroupConverter.INSTANCE.baseReceiveGroupDTOList2baseReceiveGroupDetailDTOList(baseReceiveGroupDTOList);
        if (CollectionUtils.isNotEmpty(baseReceiveGroupDetailDTOList)) {
            List<Long> groupIdList = baseReceiveGroupDetailDTOList.stream().map(BaseReceiveGroupDetailDTO::getId).collect(Collectors.toList());
            List<BaseReceiveGroupRangeDTO> receiveGroupRangeDTOList = baseReceiveGroupRangeRepository.selectByGroupIdList(groupIdList);
            Map<Long, List<BaseReceiveGroupRangeDTO>> receiveGroupRangeDTOMap = receiveGroupRangeDTOList.stream().collect(Collectors.groupingBy(BaseReceiveGroupRangeDTO::getGroupId));
            baseReceiveGroupDetailDTOList.forEach(
                    baseReceiveGroupDetailDTO -> {
                        Long id = baseReceiveGroupDetailDTO.getId();
                        List<BaseReceiveGroupRangeDTO> baseReceiveGroupRangeDTOS = receiveGroupRangeDTOMap.get(id);
                        baseReceiveGroupDetailDTO.setBaseReceiveGroupRangeDTOList(baseReceiveGroupRangeDTOS);
                    }
            );
        }
        return baseReceiveGroupDetailDTOList;
    }

    @Override
    public BaseReceiveGroupDetailDTO getByReceiveGroupCode(String receiveGroupCode) {
        BaseReceiveGroupDTO baseReceiveGroupDTO = baseReceiveGroupRepository.getByReceiveGroupCode(receiveGroupCode);
        BaseReceiveGroupDetailDTO baseReceiveGroupDetailDTO = BaseReceiveGroupConverter.INSTANCE.baseReceiveGroupDTO2baseReceiveGroupDetailDTO(baseReceiveGroupDTO);
        if (Objects.nonNull(baseReceiveGroupDetailDTO)) {
            List<BaseReceiveGroupRangeDTO> baseReceiveGroupRangeDTOList = baseReceiveGroupRangeRepository.selectByGroupId(baseReceiveGroupDetailDTO.getId());
            baseReceiveGroupDetailDTO.setBaseReceiveGroupRangeDTOList(baseReceiveGroupRangeDTOList);
        }
        return baseReceiveGroupDetailDTO;
    }
}
